package com.darwin.darwinGpuEngine.core {

    import com.darwin.darwinGpuEngine.core.geom.Face;
    import com.darwin.darwinGpuEngine.core.materials.ASpriteSheetBase;
    import com.darwin.darwinGpuEngine.core.materials.GNodeBatchMaterial;
    import com.darwin.darwinGpuEngine.core.materials.Texture2D;
    import com.darwin.darwinGpuEngine.utils.StatsObject;
    import com.darwin.darwinGpuEngine.utils.TextureHelper;
    
    import flash.display.BitmapData;
    import flash.display3D.Context3D;

    /**
     * 节点云
     * <br>一片节点云中所有节点均使用相同贴图，子节点可触发鼠标事件，添加和移除内容不会拖慢渲染效率
     */
    public class GNodeBatch extends GNode {


        public function GNodeBatch(textureObject:Object) {
            material = new GNodeBatchMaterial();
            faceList = TextureHelper.generateQuadFromDimensions(2, 2);

            if(textureObject is BitmapData) {
                texture = new Texture2D(textureObject as BitmapData);
            } else if(textureObject is Texture2D) {
                texture = textureObject as Texture2D;
            } else {
                throw new Error("材质必须为BitmapData或 Texture2D");
            }
        }

        override public function get numTris():uint {
            return material.numTris;
        }

        override public function get drawCalls():uint {
            return material.drawCalls;
        }

        override public function setSpriteSheet(value:ASpriteSheetBase):void {
            this.spriteSheet = value;
        }

        override public function addChildAt(child:GNode, idx:uint):GNode {

            if(child is GNodeBatch) {
                throw new Error("不能添加GNodeBatch为自己的子对象");
            }

            var c:GNode = child as GNode;

            // 传递spriteSheet到子对象
            if(spriteSheet && !c.spriteSheet) {
                c.spriteSheet = spriteSheet.clone();
            } else {
                c.setTexture(texture);
            }

            return super.addChildAt(child, idx);
        }

        override internal function stepNode(elapsed:Number):void {

            step(elapsed);

            for each(var child:GNode in children) {
                child.timeSinceStartInSeconds = timeSinceStartInSeconds;
                child.stepNode(elapsed);
            }

            // 不要刷新自己的spritesheet
        }

        override internal function drawNode(context:Context3D, camera:GCam, parentMatrixChanged:Boolean, statsObject:StatsObject):void {

            var myMatrixChanged:Boolean = false;

            if(!visible) {
                return;
            }

            if(invalidateColors) {
                updateColors();
            }

            if(invalidateMatrix) {
                updateMatrix();
                myMatrixChanged = true;
            }

            if(parentMatrixChanged || myMatrixChanged) {
                worldModelMatrix.identity();
                worldModelMatrix.append(localModelMatrix);

                if(parent) {
                    worldModelMatrix.append(parent.worldModelMatrix);
                }
            }

            draw(context, camera);
            statsObject.totalDrawCalls += drawCalls;
            statsObject.totalTris += numTris;

            // 不要在这里调用子对象的draw方法
        }

        override public function handleDeviceLoss():void {
            super.handleDeviceLoss();
            material.handleDeviceLoss();
        }

        override protected function draw(context:Context3D, camera:GCam):void {

            material.blendMode = blendMode;
            material.modelMatrix = worldModelMatrix;
            material.projectionMatrix = camera.projectionMatrix;
            material.viewProjectionMatrix = camera.getViewProjectionMatrix();
            material.texture = texture;
            material.spriteSheet = spriteSheet;
            (material as GNodeBatchMaterial).renderBatch(context, faceList, children);
        }
    }
}
